#include "../factory/Banana.hpp"
#include "../factory/Pear.hpp"
#include "../factory/Apple.hpp"
#include "../factory/Factory.hpp"

#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"


class fixture{
public:
    fixture(){
        factory = new Factory();
        std::cout << "fixture" << std::endl;
    }
    ~fixture(){
        delete factory;
        std::cout << "~fixture" << std::endl;
    }


public:

    // 测试水果
    int test_fruit(std::string name,int target_price ){
        int code = 0;

        // 创建水果, 使用工厂创建水果,得到水果指针
        auto fruit = factory->create_fruit(name);
        CHECK(fruit != nullptr);
        if(fruit == nullptr){
            return 5;
        }

        // 打印水果
        std::cout <<  "- ";
        fruit->print();

        // 打印水果价格
        std::cout << "    - name is " << fruit->name() << std::endl;
        std::cout << "    - price is " <<fruit->get_price() << std::endl;

        // 检查水果价格
        CHECK(fruit->get_price() == target_price);
        if(fruit->get_price() != target_price){
            code = 6;
        }

        // 删除水果
        delete fruit;
        fruit = nullptr;

        // 返回测试结果
        return code;
    }

public:
    Factory* factory;
};


// 测试水果
void test_fruit(Fruit* fruit){
    REQUIRE(fruit != nullptr);
    std::cout << fruit->name() << " price is " <<fruit->get_price() << std::endl;
}

TEST_CASE("test Fruit", "[test]") {
    std::cout << std::endl << "## test Fruit" << std::endl;
    // 创建水果
    Banana* banana = new Banana();
    Pear* pear = new Pear();
    Apple* apple = new Apple();

    // 测试水果
    test_fruit(banana);
    test_fruit(pear);
    test_fruit(apple);

    // 测试价格
    REQUIRE(banana->get_price() == 10); 
    REQUIRE(pear->get_price() == 20); 
    REQUIRE(apple->get_price() == 12); 

    // 删除水果
    delete banana;
    delete pear;
    delete apple;
}

TEST_CASE("test factory", "[test]") {
    std::cout << std::endl<< "## test factory" << std::endl;
    // 创建工厂
    Factory* factory = new Factory();
    REQUIRE(factory != nullptr);



    // 创建水果, 使用工厂创建水果,得到水果指针
    Fruit* banana = factory->create_fruit("banana");
    Fruit* pear = factory->create_fruit("pear");
    Fruit* apple = factory->create_fruit("apple");
   
    // 测试水果
    test_fruit(banana);
    test_fruit(pear);
    test_fruit(apple);

    // 测试价格
    REQUIRE(banana->get_price() == 10); 
    REQUIRE(pear->get_price() == 20); 
    REQUIRE(apple->get_price() == 12); 

    // 删除水果
    delete banana;
    delete pear;
    delete apple;
}

TEST_CASE("test fixture", "[test]") {
    std::cout << std::endl<< "## test fixture" << std::endl;
    // 创建fixture
    fixture f;

    CHECK(f.test_fruit("banana",10) == 0);
    CHECK(f.test_fruit("pear",20) == 0);
    CHECK(f.test_fruit("apple",12) == 0); 
}
